# !/usr/bin python3
# encoding: utf-8 -*-
# @file     : ddt_util.py
# @author   : 沙陌 Matongxue_2
# @Time     : 2024/1/20 15:44
# @Copyright: 北京码同学
import copy
import os

from common.file_load import load_yaml_file
from common.json_util import update_value_to_json


class GlobalData:
    apis_info = {} # 存储所有的接口定义 {"接口1":{"url":xx,"method":post},"接口2":{"url":xx,"method":post}}
    data_info = [] # 存储所有的用例信息，是一个大列表
    variables = {} # 存储所有的变量 {"变量1":xxx,"变量2":ajhs}

# 封装读取数据驱动yaml文件的方法
# D:\pycharmprojects\python20231114\apiddtframework\api\buyer\login_apis.yml
def get_yaml_data(path,data):
    if os.path.isfile(path):# 判断你传的路径是否是一个文件
        # D:\pycharmprojects\python20231114\apiddtframework\api\buyer\login_apis.yml
        basename = os.path.basename(path)
        file_name = os.path.splitext(basename)[0] # 文件名称
        ext = os.path.splitext(basename)[1] # 文件扩展名
        if ext.lower() in ['.yaml','.yml'] and (file_name.lower().startswith('test_') or file_name.lower().endswith('apis')):
            yaml_info = load_yaml_file(path)
            if isinstance(data,dict):
                data.update(yaml_info)
            elif isinstance(data,list):
                data.append(yaml_info)
    elif os.path.isdir(path): # 判断你传的路径是否是一个目录
        # 如果是目录，则读取目录下所有的内容
        for filename in os.listdir(path):
            full_path = os.path.join(path,filename) # D:\pycharmprojects\python20231114\apiddtframework\api\buyer
            get_yaml_data(full_path,data)
    return data

"""
我们直接读到的测试用例数据是不能够直接传递给pytest测试用例的，传过去不符合的执行设计，
因此我们要整合数据，将接口信息和用例数据进行整合，整合完以后得到的数据格式如下：
[
    {
        "suite_name":"立即购买测试集合"
        "setup_suite":["{接口1调用}","{接口调用2}","{db调用}"]
        "teardown_suite":["{接口1调用}","{接口调用2}","{db调用}"]
        "testcase":['{接口1}','{接口2}']
    },
    {
        "suite_name":"立即购买测试集合"
        "setup_suite":["{接口1调用}","{接口调用2}","{db调用}"]
        "teardown_suite":["{接口1调用}","{接口调用2}","{db调用}"]
        "testcase":['{接口1}','{接口2}']
    },
    {
        "suite_name":"立即购买测试集合"
        "setup_suite":["{接口1调用}","{接口调用2}","{db调用}"]
        "teardown_suite":["{接口1调用}","{接口调用2}","{db调用}"]
        "testcase":['{接口1}','{接口2}']
    }
]
"""
def data_testcases(suite_data_list:list,apis_default_data:dict):
    # 定义一个最终整合完成的数据存储变量
    testcases_data_list = []
    for suite_info_dict in suite_data_list: # 遍历所有的测试集合
        suite_flag = suite_info_dict['flag']
        if suite_flag:
            setup_suite = suite_info_dict.get('setup_suite')
            if setup_suite:
                for setup_data in setup_suite:
                    if 'api_name' in setup_data:
                        # 从接口定义信息中获取接口对应的基本信息完成替换
                        replace_api_info(setup_data,apis_default_data)
            teardown_suite = suite_info_dict.get('teardown_suite')
            if teardown_suite:
                for teardown_data in teardown_suite:
                    if 'api_name' in teardown_data:
                        # 从接口定义信息中获取接口对应的基本信息完成替换
                        replace_api_info(teardown_data,apis_default_data)

            testcases = suite_info_dict['testcases'].copy()
            for i in range(len(testcases)):
                testcase = testcases[i]
                case_flag = testcase['flag']
                if case_flag:
                    suite_info_dict_new = suite_info_dict.copy()
                    steps = testcase['steps']
                    # steps也是个列表，每个数据就是一个接口调用
                    for api_test_info in steps:
                        # 从接口定义信息中获取接口对应的基本信息完成替换
                        replace_api_info(api_test_info,apis_default_data)
                    suite_info_dict_new['testcase'] = testcase
                    del suite_info_dict_new['testcases']
                    if i!=len(testcases)-1:
                        if 'teardown_suite' in suite_info_dict_new:
                            del suite_info_dict_new['teardown_suite']
                    testcases_data_list.append(suite_info_dict_new)
    return testcases_data_list

# 从接口定义信息中获取接口对应的基本信息完成替换
def replace_api_info(api_test_info,apis_default_data:dict):
    apis_default_data = copy.deepcopy(apis_default_data) # 深度拷贝
    api_name = api_test_info['api_name']
    api_default_info = apis_default_data[api_name]
    api_test_info['url'] = api_default_info['url']
    api_test_info['headers'] = api_default_info.get('headers')
    api_test_info['method'] = api_default_info['method']
    # 根据api_test_info中的test_data，通过json替换方法将测试数据替换到默认
    # 参数之中，并赋值给当前接口测试数据
    test_data = api_test_info.get('test_data')
    if test_data:
        for params_type,new_data in test_data.items():
            for json_path,data in new_data.items():
                api_default_info[params_type] = update_value_to_json(api_default_info[params_type],json_path,data)
            api_test_info[params_type] = api_default_info[params_type]
        del api_test_info['test_data']
    else:
        api_test_info['params'] = api_default_info.get('params')
        api_test_info['data'] = api_default_info.get('data')
        api_test_info['json'] = api_default_info.get('json')
        api_test_info['files'] = api_default_info.get('files')
    return api_test_info




if __name__ == '__main__':
    get_yaml_data(r'D:\pycharmprojects\python20231114\apiddtframework\api',GlobalData.apis_info)
    # print(GlobalData.apis_info)
    get_yaml_data(r'D:\pycharmprojects\python20231114\apiddtframework\testcases',GlobalData.data_info)
    # print(GlobalData.data_info)
    print('=============')
    print(data_testcases(GlobalData.data_info, GlobalData.apis_info))